package com.wzx.core.ioc.bean;

import com.wzx.core.ioc.anootaction.Autowired;
import com.wzx.core.ioc.anootaction.Component;
import com.wzx.core.ioc.anootaction.Service;
import com.wzx.core.ioc.anootaction.Value;
import com.wzx.core.ioc.context.NameValuePropertyValue;
import com.wzx.core.ioc.context.PropertyValue;
import com.wzx.core.ioc.context.ReferPropertyValue;
import com.wzx.core.utils.ClassUtil;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class BeanDefinition {
    private String beanName;
    private Class originClass;
    private boolean lazy = false;
    private Object manualBean;
    private Map<String, PropertyValue> propertyMap = new HashMap<>();

    public static BeanDefinition newInstance(Class cls) {
        BeanDefinition bd = new BeanDefinition();
        bd.beanName = getBeanName(cls);
        bd.originClass = cls;
        for (Field field : cls.getDeclaredFields()) {
            PropertyValue pv;
            if (field.isAnnotationPresent(Value.class)) {
                pv = new NameValuePropertyValue(field.getAnnotation(Value.class).value());
            } else if (field.isAnnotationPresent(Autowired.class)) {
                pv = new ReferPropertyValue(field);
            } else {
                throw new RuntimeException("不支持的类型");
            }
            bd.propertyMap.put(field.getName(), pv);
        }
        return bd;
    }

    private static String getBeanName(Class cls) {
        String beanName = "";
        Service service = (Service) cls.getAnnotation(Service.class);
        if (service != null && !service.value().isEmpty()) {
            beanName = service.value();
        }

        Component component = (Component) cls.getAnnotation(Component.class);
        if (component != null && !component.value().isEmpty()) {
            beanName = component.value();
        }

        if (beanName.isEmpty()) {
            beanName = ClassUtil.firstWordLower(cls.getSimpleName());
        }
        return beanName;
    }


    public Class getOriginClass() {
        return originClass;
    }

    public void setOriginClass(Class originClass) {
        this.originClass = originClass;
    }

    public boolean isLazy() {
        return lazy;
    }

    public void setLazy(boolean lazy) {
        this.lazy = lazy;
    }

    public String getBeanName() {
        return beanName;
    }

    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }

    public Map<String, PropertyValue> getPropertyMap() {
        return propertyMap;
    }

    public void setPropertyMap(Map<String, PropertyValue> propertyMap) {
        this.propertyMap = propertyMap;
    }

    public Object getManualBean() {
        return manualBean;
    }

    public boolean isManualBean() {
        return manualBean != null;
    }

    public void setManualBean(Object manualBean) {
        this.manualBean = manualBean;
    }
}
